/*
****************************************************************************************
* @FilePath     : app_console.c
* @brief        :
* @author       : L0131 - guomingpeng 952856693@qq.com
* @attention    : Copyright (c) 2024 awptech.co.ltd. All rights reserved.
****************************************************************************************
*/
#include <stdlib.h>
#include "cmsis_os.h"
#include "shell.h"
#include "usart.h"
#include "app_sys.h"
#include "elog.h"
#include "bsp_uart.h"
#include "app_cmd_debug.h"
#include "app_sys.h"

#define LOG_TAG "cmd_debug"

#define CONSOLE_BUF_LENGTH 20
#define CONSOLE_BUF_COUNTS 20
#define BUFF_SIZE 512

typedef struct
{
    uint8_t buffer[BUFF_SIZE];
    uint16_t buf_index;
} handle_buf_t;

volatile handle_buf_t handle_buf = {0};

static Shell shell;
static char shellBuffer[512];
static uint8_t rx_data;

extern osMutexId_t mutex_consoleHandle;

// static void rx3_noise_tho_cmd(int argc, char *argv[])
// {
//     if (argc == 3)
//     {
//         int id = atoi(argv[1]);
//         float value = atof(argv[2]);
//         if (id == 1)
//         {
//             nonlinear_app_806.rx3_noise.a1_tho = value;
//         }
//         else if (id == 2)
//         {
//             nonlinear_app_806.rx3_noise.a2_tho = value;
//         }
//         else if (id == 3)
//         {
//             nonlinear_app_806.rx3_noise.a3_tho = value;
//         }
//     }
//     log_i("current ant1 rx3 noise tho: %f", nonlinear_app_806.rx3_noise.a1_tho);
//     log_i("current ant2 rx3 noise tho: %f", nonlinear_app_806.rx3_noise.a2_tho);
//     log_i("current ant3 rx3 noise tho: %f", nonlinear_app_806.rx3_noise.a3_tho);
// }
// SHELL_EXPORT_CMD(
//     SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)|SHELL_CMD_DISABLE_RETURN,
//     rx3_noise, rx3_noise_tho_cmd, set rx3 noise tho);

static void tx_freq_cmd(int argc, char *argv[])
{
    if (argc == 2)
    {
        int freq = atoi(argv[1]);
        if (freq < 2400 || freq > 2500)
        {
            log_e("set tx freq: %d (<2400 or >2500)", freq);
            return;
        }

        app_sys_para.tx_freq = freq;
    }

    log_i("tx freq: %d", app_sys_para.tx_freq);
}
SHELL_EXPORT_CMD(
    SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN,
    tx_freq, tx_freq_cmd, set tx freq : 2400 - 2500 Hz);

static void get_phase_cmd(int argc, char *argv[])
{
    printf("%d\r\n", app_sys_para.display_value);
}
SHELL_EXPORT_CMD(
    SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_DISABLE_RETURN,
    get_phase, get_phase_cmd, get phase cmd);

/**
 * @brief 用户shell写
 *
 * @param data 数据
 * @param len 数据长度
 *
 * @return short 实际写入的数据长度
 */
static short console_write(char *data, unsigned short len)
{
    plf_uart3_send_sync((uint8_t *)data, len);
    return len;
}

/**
 * @brief 用户shell读
 *
 * @param data 数据
 * @param len 数据长度
 *
 * @return short 实际读取到
 */
static short console_read(char *data, unsigned short len)
{
    /* 在串口接收数据时处理 */
    return 0;
}

/**
 * @brief 用户shell上锁
 *
 * @param shell shell
 *
 * @return int 0
 */
static int console_lock(Shell *shell)
{
    osMutexWait(mutex_consoleHandle, osWaitForever);
    return 0;
}

/**
 * @brief 用户shell解锁
 *
 * @param shell shell
 *
 * @return int 0
 */
static int console_unlock(Shell *shell)
{
    osMutexRelease(mutex_consoleHandle);
    return 0;
}

static void console_recv_data_handler(uint8_t *buf, uint16_t recv_len)
{
    uint16_t memcpy_len = 0;
    memcpy_len = recv_len > (BUFF_SIZE - handle_buf.buf_index) ? (BUFF_SIZE - handle_buf.buf_index) : recv_len;
    if (memcpy_len)
    {
        memcpy(&handle_buf.buffer[handle_buf.buf_index], buf, memcpy_len);
        handle_buf.buf_index += memcpy_len;
    }
}

/**
 * @brief 用户shell初始化
 *
 */
static void console_init(void)
{
    shell.write = console_write;
    shell.read = console_read;
    shell.lock = console_lock;
    shell.unlock = console_unlock;
    shellInit(&shell, shellBuffer, 512);

    plf_uart3_init();
    plf_uart3_recv_callback_register(console_recv_data_handler);
    // plf_uart3_recv_async(console_buf_rx.buffer[console_buf_rx.cur_buf_index], CONSOLE_BUF_LENGTH);
    plf_uart3_recv_async(NULL, 0);
}

static void console_recv_data_handle(uint8_t *buf, uint16_t len)
{
    // log_d("console_recv_data_handle: %s \r\n", buf);
    while (len)
    {
        shellHandler(&shell, *(buf++));
        len--;
    }
}

void task_app_console(void)
{
    uint16_t start_index = 0, end_index = 0;

    memset(&handle_buf.buffer[0], 0x00, BUFF_SIZE);

    console_init();

    for (;;)
    {
        static uint32_t test_tick = 0;
        test_tick++;
        if (test_tick > 20)
        {
            test_tick = 0;
            // log_d("app_console loop \r\n");
        }

        end_index = handle_buf.buf_index;
        if (start_index != end_index)
        {
            console_recv_data_handle(&handle_buf.buffer[start_index], end_index - start_index);
            start_index = end_index;

            /* 在处理过程中没有新的数据进来 */
            if (handle_buf.buf_index == end_index)
            {
                memset(&handle_buf.buffer[0], 0x00, BUFF_SIZE);
                handle_buf.buf_index = 0;
                end_index = 0;
                start_index = 0;
            }
        }

        osDelay(50);
    }
}
